const { resolve, join } = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');
// const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const config = require('../public/config.json');
// const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
// const TerserPlugin = require('terser-webpack-plugin');
// 获取处理样式的Loaders

console.log(config, 'config');

const getStyleLoaders = (isProd, preProcessor) => {
    return [
        "style-loader",
        "css-loader",
        {
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: [
                        // 'autoprefixer',
                        'postcss-preset-env'// 能解决大多数样式兼容性问题
                    ],
                },
            },
        },
        preProcessor,
    ].filter(Boolean);
};
module.exports = (env) => ({
    entry: './src/index.tsx',
    output: {
        filename: 'script/[name].[contenthash].bundle.js',
        path: env.production ? resolve(__dirname, '../dist') : undefined,
        clean: true, // 打包前清理 dist 文件夹
    },
    // loader 配置
    module: {
        rules: [
            {
                // 匹配一个就结束
                oneOf: [
                    /**
                     * cacheDirectory: 这个选项用于启用缓存机制。当true时，babel-loader会将转换后的文件缓存到一个指定的目录下。这样，下一次编译时，
                     * 如果文件没有改变，babel-loader可以直接从缓存中读取已经转换过的文件，而不是重新进行转换。这可以显著加快编译速度，特别是在大型项目中。
                     */
                    {
                        test: /\.(js|jsx|ts|tsx)$/, // 匹配 .js 和 .jsx .ts .tsx文件 
                        exclude: /node_modules/,
                        use: {
                            loader: 'babel-loader',
                            // Babel 会将转换后的文件缓存到 node_modules/.cache/babel-loader/ 目录中。
                            options: {
                                cacheDirectory: false, // 启用缓存
                            }
                        }
                    },
                    // less
                    /**
                     * * 1. style-loader: 将 JS 字符串生成为 style 节点 然后插入到创建style标签插到head下
                     * * 2. css-loader: 将 CSS 文件转换为 CommonJS 模块 将 css 解析成 js，但不能挂载到元素上
                     * * * 3. less-loader: 将 less 文件转换为 css 文件
                     * 使用CSS3的一些新特性时，需要为不同的浏览器在CSS代码中添加不同的前缀，在开发中手动添加太麻烦，
                     * 所以我们可以通过postcss来自动添加各种浏览器前缀。
                     * autoprefixer 用来添加浏览器前缀、 cssnano 用来压缩 CSS、
                     *  postcss-preset-env 用来根据目标浏览器生成 CSS的 polyfill
                     * 
                     * postcss-loader的option
                     * 旧版
                     * 
                     *  {
                            loader: 'postcss-loader',
                            options: {
                            plugins: [
                                require('autoprefixer'),
                                // 其他 PostCSS 插件
                            ],
                            },
                        },
                        要是想postcss-loader生成浏览器前缀配置还需要在package.json中
                        配置browserslist浏览器兼容性配置
                     */
                    // css
                    {
                        test: /\.css$/, use: getStyleLoaders(env.production)
                    },
                    {
                        test: /\.less$/, use: getStyleLoaders(env.production, 'less-loader')
                    },
                    // sass
                    {
                        test: /\.s[ac]ss$/i, use: getStyleLoaders(env.production, 'sass-loader')
                    },
                    // 静态资源
                    // { test: /\.(png|jpg|gif|svg|ico)$/, type: 'asset', generator: { filename: 'assets/[name][ext]' } } //传统
                    {                                       //配置图片静态资源的打包信息
                        test: /\.(jpg|png|jpeg|gif)$/,
                        use: [
                            {
                                loader: 'url-loader',
                                options: {
                                    limit: 1024,
                                    fallback: {
                                        loader: 'file-loader',
                                        options: {
                                            name: 'img/[name].[hash:8].[ext]'
                                        }
                                    }
                                }
                            }
                        ]
                    },
                    {                                       //配置多媒体资源的打包信息
                        test: /\.(mp4|webm|ogg|mp3|wav)$/,
                        use: [
                            {
                                loader: 'url-loader',
                                options: {
                                    limit: 1024,
                                    fallback: {
                                        loader: 'file-loader',
                                        options: {
                                            name: 'media/[name].[hash:8].[ext]'
                                        }
                                    }
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    },
    resolve: {
        // 简化模块导入的过程
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
        alias: {
            pages: join(__dirname, '../src/pages'),
            layouts: join(__dirname, '../src/layouts'),
            components: join(__dirname, '../src/components'),
            actions: join(__dirname, '../src/redux/actions'),
            reducers: join(__dirname, '../src/redux/reducers'),
            images: join(__dirname, '../src/images'),
            utils: join(__dirname, '../src/utils'),
        }
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: resolve(__dirname, "../public/index.html"),
            filename: config.OPENHTMLHASH && env.production ? 'index.[contenthash:8].html' : 'index.html',
            // 压缩html资源  生产压缩 否则不压缩
            minify: env.production ? {
                collapseWhitespace: true, //去空格
                removeComments: true // 去注释
            } : false
        }),
        new webpack.DefinePlugin({
            SET_CONFIG_PATH: config
        })
    ],
})